/*
 * Description: 
 *     History: yang@haipo.me, 2017/03/18, create
 */

# include "me_config.h"
# include "me_update.h"
# include "me_balance.h"
# include "me_history.h"
# include "me_message.h"

struct update_key : public mem_dict_key<update_key>{
    uint32_t    user_id;
    char        asset[ASSET_NAME_MAX_LEN + 1];
    char        business[BUSINESS_NAME_MAX_LEN + 1];
    uint64_t    business_id;
};

struct update_val : public mem_dict_value<update_val>{
    double create_time;
};

static dict_plus<update_key*, update_val*> *dict_update;
static nw_timer timer;

/*
 * 一分钟调用一次 清理一天以前的缓存
 * */
static void on_timer(nw_timer *t, void *privdata)
{
    double now = current_timestamp();
    auto iter = dict_update->get_iterator();
    for(auto entry = iter->next(); entry != NULL; entry = iter->next()) {
        if (entry->get_value()->create_time < (now - 86400)) {
            dict_update->remove(entry->get_key());
        }
    }
    iter->release();
}

int init_update(void)
{
    dict_update = dict_plus<update_key*, update_val*>::create(64);
    if (dict_update == NULL)
        return -__LINE__;

    nw_timer_set(&timer, 60, true, on_timer, NULL);
    nw_timer_start(&timer);

    return 0;
}

/*
    更新用户余额 去重
*/
int update_user_balance(bool real, uint32_t user_id, const char *asset, const char *business, uint64_t business_id, mpd_t *change, json_t *detail)
{
    update_key key;
    key.user_id = user_id;
    strncpy(key.asset, asset, sizeof(key.asset));
    strncpy(key.business, business, sizeof(key.business));
    key.business_id = business_id;

    auto entry = dict_update->find(&key);
    if (entry) {
        return -1;
    }

    mpd_t *result;
    mpd_t *abs_change = mpd_new(&mpd_ctx);
    mpd_abs(abs_change, change, &mpd_ctx);

    if (mpd_cmp(change, mpd_zero, &mpd_ctx) >= 0) {
        result = balance_add(user_id, BALANCE_TYPE_AVAILABLE, asset, abs_change);
    } else {
        result = balance_sub(user_id, BALANCE_TYPE_AVAILABLE, asset, abs_change);
    }
    mpd_del(abs_change);

    if (result == NULL)
        return -2;

    update_val val;
    val.create_time = current_timestamp();
    dict_update->add(&key, &val);

    if (real) {
        double now = current_timestamp();
        json_object_set_new(detail, "id", json_integer(business_id));
        char *detail_str = json_dumps(detail, 0);

        append_user_balance_history(now, user_id, asset, business, change, detail_str);

        push_balance_message(now, user_id, asset, business, change);

        free(detail_str);
    }
    return 0;
}